/*
 * Copyright 2022 The Open Islands Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.openislands.oi.util;

import java.io.IOException;
import java.util.*;

import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.yaml.snakeyaml.Yaml;

public class YamlUtils {
    /***
     * load (.yml or .yaml) file to properties from conf path or classpath
     * @return {@link Properties}
     * @throws IOException not found source
     */
    public static Properties loadYamlProperties(String fileName) throws IOException {
        Resource resource = new FileSystemResource("conf/" + fileName);
        if (!resource.exists()) {
            resource = new ClassPathResource(fileName);
        }

        if (!resource.exists()) {
            throw new IOException("load source failed. not found " + fileName);
        } else {
            Yaml yaml = new Yaml();
            Properties properties = new Properties();
            Map<String, Object> load = yaml.load(resource.getInputStream());
            properties.putAll(load);
            return properties;
        }
    }

    /***
     * load (.yml or .yaml) file to PropertySource from conf path or classpath
     * yaml:
     *   key: value
     * ===>
     * {"yaml.key" : value}
     */
    public static PropertySource<?> loadYamlSource(String fileName) throws IOException {
        YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
        final Map<String, Object> load = new LinkedHashMap<>();

        Resource[] loadResources = {new FileSystemResource("conf/" + fileName), new ClassPathResource(fileName)};
        List<PropertySource<?>> sources;
        for (Resource loadResource : loadResources) {
            if (loadResource.exists() && !(sources = loader.load(fileName, loadResource)).isEmpty()) {
                OriginTrackedMapPropertySource source = ((OriginTrackedMapPropertySource) sources.get(0));
                load.putAll(source.getSource());
            }
        }

        if (load.isEmpty()) {
            throw new IOException("load source " + fileName + " failed.");
        } else {
            return new OriginTrackedMapPropertySource(fileName, Collections.unmodifiableMap(load), true);
        }
    }
}
